#include "bsp_int.h"

/**
 *  中断驱动文件 
 */


/*中断嵌套计数器*/
static unsigned int irqNesting;

/*中断服务函数表*/
static sys_irq_handle_t irqTables[NUMBER_OF_INT_VECTORS];  //sys_irq_handle_t类型的数组   NUMBER_OF_INT_VECTORS这个在MCIMX6Y2.h中有定义

/**
 *  @brief :中断初始化函数
 *  @param :无
 *  @retval :无
 */
void int_init(void)
{
    GIC_Init();                                         //在core_ca7.h中定义
    system_irqtable_init();                             //初始化中断表
    __set_VBAR((uint32_t)0X87800000);                   //中断向量表偏移 这个是C语言版的
}

/**
 *  @brief 给指定的中断号注册中断服务函数
 *  @param irq 要注册的中断号
 *  @param handler 要注册的中断处理函数
 *  @param userParam 中断服务处理函数参数
 *  @retval :无
 */
void system_register_irqhandler(IRQn_Type irq,system_irq_handler_t handler,void *userParam)
{   //这是一个结构体类型的数组
    irqTables[irq].irqHandler=handler;  //这里是函数指针
    irqTables[irq].userParam=userParam; //这里传递的都是地址值
}

/**
 *  @brief 默认中断服务函数
 *  @param gicciar 中断号
 *  @param userParam 中断服务处理函数参数
 *  @retval :无
 */
void default_irqhandler(uint32_t gicciar,void *userParam)
{
    while (1)
    {
        ;
    }
}

/**
 *  @brief :初始化中断服务函数
 *  @param :无
 *  @retval :无
 */
void system_irqtable_init(void)
{
    uint32_t i=0;
    irqNesting=0;

    /*先将所有的中断服务函数设置为默认值  可以认为是初始化*/
    for(i=0; i< NUMBER_OF_INT_VECTORS;i++)  //这160个中断都得进行初始化
    {   
        system_register_irqhandler((IRQn_Type)i,default_irqhandler,NULL);
    }
}

/**
 *  @brief  C语言中断服务函数,irq汇编中断服务函数会调用此函数,此函数通过在中断服务列表中查找指定中断号所对应的中断处理函数并执行
 *  @param  中断号  这个形参是通过r0寄存器传进来的
 *  @return 无
 */
void system_irqhandler(uint32_t gicciar)  
{
    uint32_t intNum=gicciar & 0X3FFUL;  //0 ~ 1023 

    /*检查中断号是否符合要求  每个CPU最多支持1020个中断ID*/
    if((intNum ==1020) || (intNum >= NUMBER_OF_INT_VECTORS))
    {
        return;
    } 

    irqNesting++;  //中断嵌套计数器加1   (uint32_t gicciar,void *param);
    irqTables[intNum].irqHandler(intNum,irqTables[intNum].userParam);   //  
    irqNesting--;  //中断嵌套计数器减1
}